/*******************************************************************************
  * @file                   mqos_task.c
  * @Author:                MQjehovah                 mail:MQjehovah@hotmail.com
  * @version                1.0.0
  * @date                   2017.7.25
  * @brief                  
  ******************************************************************************
  * @attention				create a new os
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "mqos_task.h"
/* Definition ----------------------------------------------------------------*/
MQOS_STATUS MQOS_STATUS_Table[MQOS_LOWEST_PRIO]={0};


/* Functions -----------------------------------------------------------------*/
/*******************************************************************************
  * @brief  设置任务状态       
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
void MQOS_Task_SetPrio(u8 id, MQOS_STATUS status)
{
	if(id>MQOS_LOWEST_PRIO){
		MQOS_STATUS_Table[id] = status;
	}
}

/*******************************************************************************
  * @brief  更新当前任务状态表中优先级最高的就绪态任务       
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
void MQOS_Task_GetHighPrio()
{
	u32 pTask;
	for(pTask=0;(NextPrio < MQOS_LOWEST_PRIO)&&(MQOS_STATUS_Table[pTask]!= MQOS_STATUS_READY);pTask++){
		MQOS_HIGHRdy = status;
	}
}

/*******************************************************************************
  * @brief  create task       
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
void MQOS_Task_Create(void (*task)(void), MQOS_TCB tcb, MQOS_STK *stk)
{
	MQOS_STK *p_stk;
	p_stk = stk;
	p_stk = (MQOS_STK *)((MQOS_STK)p_stk&0xfffffff8u);

    *(--p_stk) = (STACK_TypeDef)0x01000000uL;                          //xPSR
    *(--p_stk) = (STACK_TypeDef)task;                                  // Entry Point
    *(--p_stk) = (STACK_TypeDef)0x14141414uL;                          // R14 (LR)
    *(--p_stk) = (STACK_TypeDef)0x12121212uL;                          // R12
    *(--p_stk) = (STACK_TypeDef)0x03030303uL;                          // R3
    *(--p_stk) = (STACK_TypeDef)0x02020202uL;                          // R2
    *(--p_stk) = (STACK_TypeDef)0x01010101uL;                          // R1
    *(--p_stk) = (STACK_TypeDef)0x00000000u;                           // R0

    *(--p_stk) = (STACK_TypeDef)0x11111111uL;                          // R11
    *(--p_stk) = (STACK_TypeDef)0x10101010uL;                          // R10
    *(--p_stk) = (STACK_TypeDef)0x09090909uL;                          // R9
    *(--p_stk) = (STACK_TypeDef)0x08080808uL;                          // R8
    *(--p_stk) = (STACK_TypeDef)0x07070707uL;                          // R7
    *(--p_stk) = (STACK_TypeDef)0x06060606uL;                          // R6
    *(--p_stk) = (STACK_TypeDef)0x05050505uL;                          // R5
    *(--p_stk) = (STACK_TypeDef)0x04040404uL;                          // R4

    TCB[t_Prio].StkAddr = p_stk;
    TCB[t_Prio].OSTCBDly = 0;
    TCB[t_Prio].State = TASK_READY;
}

/*******************************************************************************
  * @brief  change task priority      
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
MQOS_RET MQOS_Task_ChangePrio(u8 oldprio,u8 newprio)
{
    OS_TCB    *ptcb;
	
    if (oldprio >= OS_LOWEST_PRIO || newprio >= OS_LOWEST_PRIO) {
        return (MQOS_RET_PRIO_INVALID);
    }

    OS_ENTER_CRITICAL();
    if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) {             /* New priority must not already exist     */
        OS_EXIT_CRITICAL();
        return (OS_ERR_PRIO_EXIST);
    }
    if (oldprio == OS_PRIO_SELF) {                          /* See if changing self                    */
        oldprio = OSTCBCur->OSTCBPrio;                      /* Yes, get priority                       */
    }
    ptcb = OSTCBPrioTbl[oldprio];
    if (ptcb == (OS_TCB *)0) {                              /* Does task to change exist?              */
        OS_EXIT_CRITICAL();                                 /* No, can't change its priority!          */
        return (OS_ERR_PRIO);
    }
    if (ptcb == OS_TCB_RESERVED) {                          /* Is task assigned to Mutex               */
        OS_EXIT_CRITICAL();                                 /* No, can't change its priority!          */
        return (OS_ERR_TASK_NOT_EXIST);
    }

    OSTCBPrioTbl[oldprio] = (OS_TCB *)0;                    /* Remove TCB from old priority            */
    OSTCBPrioTbl[newprio] =  ptcb;                          /* Place pointer to TCB @ new priority     */

    ptcb->OSTCBPrio = newprio;                              /* Set new task priority                   */
    ptcb->OSTCBY    = y_new;
    ptcb->OSTCBX    = x_new;
    ptcb->OSTCBBitY = bity_new;
    ptcb->OSTCBBitX = bitx_new;
    OS_EXIT_CRITICAL();
    if (OSRunning == OS_TRUE) {
        OS_Sched();                                         /* Find new highest priority task          */
    }
    return (OS_ERR_NONE);
}
/*********************************END OF FILE**********************************/
